home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / windows / comms / recomm10.arj / LNKLIST.C < prev    next >
C/C++ Source or Header  |  1993-10-11  |  23KB  |  564 lines

  1. /****************************************************************************
  2.  * Program Name...  LnkList.OBJ
  3.  * Filename.......  LnkList.C
  4.  * Author.........  John A. Kuhn
  5.  * Version........  1.0
  6.  * Version Date...  June 8, 1992
  7.  * Comments.......  Generic linked list routines - this module uses
  8.  *                  the caller's data segment -GW
  9.  *
  10.  * $Header$
  11.  * $Modtime$
  12.  * $Log$
  13.  *
  14.  ***************************************************************************/
  15.  
  16. #include <windows.h>
  17. #include "wnetbios.h"
  18.  
  19. /* internal function prototypes */
  20.  
  21. static HANDLE CreateListItemNode(HANDLE hItemData,
  22.                                  HANDLE hPrevItem,
  23.                                  HANDLE hNextItem);
  24.  
  25. static HANDLE GetListItemNode(HANDLE hListHead, WORD wItemIndex);
  26. static WORD   GetListItemIndex(HANDLE hListHead, HANDLE hListItem);
  27.  
  28.  
  29. /*====================================================================*/
  30. /*                                                                    */
  31. /*                     Internal Functions                             */
  32. /*                                                                    */
  33. /*====================================================================*/
  34.  
  35.  
  36. /*--------------------------------------------------------------------*/
  37. /* CreateListItem                                                     */
  38. /*                                                                    */
  39. /*     This function creates a unlinked list item node by alloc'ing   */
  40. /*     memory for a node and assigns the specified item data handle   */
  41. /*     next item handle to it.                                        */
  42. /*                                                                    */
  43. /*  Arguments:                                                        */
  44. /*                                                                    */
  45. /*     hItemData   = Handle to item data                              */
  46. /*     hPrevItem   = Handle to previous item node                     */
  47. /*     hNextItem   = Handle to next item node                         */
  48. /*                                                                    */
  49. /*  Globals:       None                                               */
  50. /*                                                                    */
  51. /*  Return:        Returns a handle to the list item node or NULL     */
  52. /*                 if it failed to create node.                       */
  53. /*                                                                    */
  54. /*--------------------------------------------------------------------*/
  55. static HANDLE CreateListItemNode(HANDLE hItemData,
  56.                                  HANDLE hPrevItem,
  57.                                  HANDLE hNextItem)
  58. {
  59.    HANDLE hListItem;
  60.    NPLISTITEM npListItem;
  61.  
  62.    hListItem = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE, sizeof(LISTITEM));
  63.    if (hListItem != NULL)
  64.    {
  65.        npListItem = (NPLISTITEM) GlobalLock(hListItem);
  66.        npListItem->hItemData = hItemData;
  67.        npListItem->hPrevItem = hPrevItem;
  68.        npListItem->hNextItem = hNextItem;
  69.        GlobalUnlock(hListItem);
  70.    }
  71.  
  72.    return(hListItem);
  73. }
  74.  
  75.  
  76. /*--------------------------------------------------------------------*/
  77. /* GetListItemNode                                                    */
  78. /*                                                                    */
  79. /*     This function traverses through the specified linked list      */
  80. /*     and returns the handle to the specified items node.            */
  81. /*                                                                    */
  82. /*  Arguments:                                                        */
  83. /*                                                                    */
  84. /*     hListHead   = Handle of the lists header node.                 */
  85. /*     wItemIndex  = Index of List item node (based at 1)             */
  86. /*                   An index not in list returns NULL.               */
  87. /*                                                                    */
  88. /*  Globals:       None                                               */
  89. /*                                                                    */
  90. /*  Return:        Returns the handle of the specified list item      */
  91. /*                 node or NULL if item not in list.                  */
  92. /*                                                                    */
  93. /*--------------------------------------------------------------------*/
  94. HANDLE GetListItemNode(HANDLE hListHead, WORD wItemIndex)
  95. {
  96.    NPLISTHEAD npList;
  97.    NPLISTITEM npNextItem;
  98.    HANDLE     hNextItem;
  99.    WORD       wNoListItems;
  100.    WORD       wIndex = 0;
  101.    HANDLE     hItem = NULL;
  102.  
  103.    npList = (NPLISTHEAD) GlobalLock(hListHead);
  104.    if (npList == NULL)
  105.       return (NULL);
  106.  
  107.    wNoListItems = npList->wCount;
  108.    hNextItem = npList->hFirstItem;
  109.    GlobalUnlock(hListHead);
  110.  
  111.    if (wItemIndex == 0 || wItemIndex > wNoListItems)
  112.       return(NULL);
  113.  
  114.    while (hNextItem != NULL && wIndex != wItemIndex)
  115.    {
  116.        hItem = hNextItem;
  117.        npNextItem = (NPLISTITEM) GlobalLock(hNextItem);
  118.        hNextItem = npNextItem->hNextItem;
  119.        GlobalUnlock(hNextItem);
  120.        ++wIndex;
  121.    }
  122.  
  123.    return(hItem);
  124.  
  125. }
  126.  
  127.  
  128. /*--------------------------------------------------------------------*/
  129. /* GetListItemIndex                                                   */
  130. /*                                                                    */
  131. /*     This function traverses through the specified linked list      */
  132. /*     and returns the index of the list item node with the specified */
  133. /*     handle.                                                        */
  134. /*                                                                    */
  135. /*  Arguments:                                                        */
  136. /*                                                                    */
  137. /*     hListHead   = Handle of the lists header node.                 */
  138. /*     hListItem   = Handle of List item node.                        */
  139. /*                                                                    */
  140. /*  Globals:       None                                               */
  141. /*                                                                    */
  142. /*  Return:        Returns the index of the specified list item node  */
  143. /*                 or 0 if item does not exist.                       */
  144. /*                                                                    */
  145. /*--------------------------------------------------------------------*/
  146. static WORD GetListItemIndex(HANDLE hListHead, HANDLE hListItem)
  147. {
  148.    NPLISTHEAD npList;
  149.    NPLISTITEM npNextItem;
  150.    HANDLE     hNextItem;
  151.    WORD       wIndex = 0;
  152.  
  153.    npList = (NPLISTHEAD) GlobalLock(hListHead);
  154.    hNextItem = npList->hFirstItem;
  155.    GlobalUnlock(hListHead);
  156.  
  157.    while (hNextItem != hListItem && hNextItem != NULL)
  158.    {
  159.        npNextItem = (NPLISTITEM) GlobalLock(hNextItem);
  160.        hNextItem = npNextItem->hNextItem;
  161.        GlobalUnlock(hNextItem);
  162.        ++wIndex;
  163.    }
  164.  
  165.    if (hNextItem != NULL)
  166.        return (wIndex);
  167.    else
  168.        return (0);
  169. }
  170.  
  171.  
  172. /*====================================================================*/
  173. /*                                                                    */
  174. /*                     A P I    Functions                             */
  175. /*                                                                    */
  176. /*====================================================================*/
  177.  
  178.  
  179. /*--------------------------------------------------------------------*/
  180. /* CreateLinkedList                                                   */
  181. /*                                                                    */
  182. /*     This function ...                                              */
  183. /*                                                                    */
  184. /*  Arguments:     None                                               */
  185. /*                                                                    */
  186. /*  Globals:       None                                               */
  187. /*                                                                    */
  188. /*  Return:        None                                               */
  189. /*                                                                    */
  190. /*--------------------------------------------------------------------*/
  191. HANDLE FAR PASCAL CreateLinkedList(void)
  192. {
  193.    HANDLE     hListHead;
  194.    NPLISTHEAD npList;
  195.  
  196.    hListHead = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE, sizeof(LISTHEAD));
  197.  
  198.    if (hListHead != NULL)
  199.    {
  200.        npList = (NPLISTHEAD) GlobalLock(hListHead);
  201.        npList->wCount = 0;
  202.        npList->hLastItem  = NULL;
  203.        npList->hFirstItem = NULL;
  204.        GlobalUnlock(hListHead);
  205.    }
  206.  
  207.    return(hListHead);
  208. }
  209.  
  210.  
  211. /*--------------------------------------------------------------------*/
  212. /* AddListItem                                                        */
  213. /*                                                                    */
  214. /*     This function adds a list item to the end of the specified     */
  215. /*     list.                                                          */
  216. /*                                                                    */
  217. /*  Arguments:                                                        */
  218. /*                                                                    */
  219. /*     hListHead   = Handle of the lists header node.                 */
  220. /*     hItemData   = Handle of list item data                         */
  221. /*                                                                    */
  222. /*  Globals:       None                                               */
  223. /*                                                                    */
  224. /*  Return:        Returns TRUE if successful else FALSE              */
  225. /*                                                                    */
  226. /*--------------------------------------------------------------------*/
  227. BOOL FAR PASCAL AddListItem(HANDLE hListHead, HANDLE hItemData)
  228. {
  229.    NPLISTHEAD npList;
  230.    NPLISTITEM npItem;
  231.    HANDLE     hItem;
  232.  
  233.    npList = (NPLISTHEAD) GlobalLock(hListHead);
  234.    if (npList == NULL)
  235.       return (FALSE);
  236.  
  237.    if (npList->wCount == MAX_LIST_COUNT)
  238.    {
  239.       GlobalUnlock(hListHead);
  240.       return (FALSE);
  241.    }
  242.  
  243.    hItem = CreateListItemNode(hItemData, npList->hLastItem, NULL);
  244.  
  245.    if (hItem == NULL)
  246.    {
  247.       GlobalUnlock(hListHead);
  248.       return (FALSE);
  249.    }
  250.  
  251.    if (npList->hFirstItem == NULL)
  252.    {
  253.       npList->hFirstItem = hItem;
  254.    }
  255.    else
  256.    {
  257.       npItem = (NPLISTITEM) GlobalLock(npList->hLastItem);
  258.       npItem->hNextItem = hItem;
  259.       GlobalUnlock(npList->hLastItem);
  260.    }
  261.  
  262.    npList->hLastItem = hItem;
  263.  
  264.    ++npList->wCount;
  265.    GlobalUnlock(hListHead);
  266.    return (TRUE);
  267. }
  268.  
  269.  
  270. /*--------------------------------------------------------------------*/
  271. /* DeleteListItem                                                     */
  272. /*                                                                    */
  273. /*     This function deletes the specified list item node             */
  274. /*     from the specified list.                                       */
  275. /*                                                                    */
  276. /*  Arguments:                                                        */
  277. /*                                                                    */
  278. /*     hListHead   = Handle of the lists header node.                 */
  279. /*     wItemIndex  = Index of a list item                             */
  280. /*                                                                    */
  281. /*  Globals:       None                                               */
  282. /*                                                                    */
  283. /*  Return:        Returns TRUE if successfull else FALSE if failed   */
  284. /*                 because list item does not exist.                  */
  285. /*                                                                    */
  286. /*--------------------------------------------------------------------*/
  287. BOOL FAR PASCAL DeleteListItem(HANDLE hListHead, WORD wItemIndex)
  288. {
  289.    HANDLE     hItem;
  290.    NPLISTITEM npPrevItem, npNextItem, npItem;
  291.    NPLISTHEAD npList;
  292.  
  293.    npList = (NPLISTHEAD) GlobalLock(hListHead);
  294.    if (npList == NULL)
  295.       return(FALSE);
  296.  
  297.    if (wItemIndex == 0 || wItemIndex > npList->wCount)
  298.    {
  299.       GlobalUnlock(hListHead);
  300.       return(FALSE);
  301.    }
  302.  
  303.    hItem = GetListItemNode(hListHead, wItemIndex);
  304.    if (hItem == NULL)
  305.    {
  306.       GlobalUnlock(hListHead);
  307.       return(FALSE);
  308.    }
  309.  
  310.    npItem = (NPLISTITEM) GlobalLock(hItem);
  311.  
  312.    if (npItem->hNextItem != NULL)
  313.    {
  314.       npNextItem = (NPLISTITEM) GlobalLock(npItem->hNextItem);
  315.       npNextItem->hPrevItem = npItem->hPrevItem;
  316.       GlobalUnlock(npItem->hNextItem);
  317.    }
  318.  
  319.    if (npItem->hPrevItem != NULL)
  320.    {
  321.       npPrevItem = (NPLISTITEM) GlobalLock(npItem->hPrevItem);
  322.       npPrevItem->hNextItem = npItem->hNextItem;
  323.       GlobalUnlock(npItem->hPrevItem);
  324.    }
  325.  
  326.    if (hItem == npList->hFirstItem)
  327.       npList->hFirstItem = npItem->hNextItem;
  328.  
  329.    if (hItem == npList->hLastItem)
  330.       npList->hLastItem = npItem->hPrevItem;
  331.  
  332.    // delete the items node
  333.    GlobalUnlock(hItem);
  334.    GlobalFree(hItem);
  335.  
  336.    --npList->wCount;
  337.    GlobalUnlock(hListHead);
  338.    return (TRUE);
  339. }
  340.  
  341. /*--------------------------------------------------------------------*/
  342. /* InsertListItem                                                     */
  343. /*                                                                    */
  344. /*     This function inserts a list item before the specified item    */
  345. /*     of the specified list.                                         */
  346. /*                                                                    */
  347. /*  Arguments:                                                        */
  348. /*                                                                    */
  349. /*     hListHead   = Handle of the lists header node.                 */
  350. /*     hItemData   = Handle of list item data                         */
  351. /*     wItemIndex  = Index of a list item                             */
  352. /*                                                                    */
  353. /*                                                                    */
  354. /*  Globals:       None                                               */
  355. /*                                                                    */
  356. /*  Return:        Returns TRUE if successfull else FALSE             */
  357. /*                                                                    */
  358. /*--------------------------------------------------------------------*/
  359. BOOL FAR PASCAL InsertListItem(HANDLE hListHead, HANDLE hItemData, WORD wItemIndex)
  360. {
  361.    HANDLE     hNewItem, hItem;
  362.    NPLISTITEM npItem, npPrevItem;
  363.    NPLISTHEAD npList;
  364.  
  365.    npList = (NPLISTHEAD) GlobalLock(hListHead);
  366.  
  367.    if (npList == NULL)
  368.       return (FALSE);
  369.  
  370.    if (npList->wCount == MAX_LIST_COUNT)
  371.    {
  372.       GlobalUnlock(hListHead);
  373.       return (FALSE);
  374.    }
  375.  
  376.    if (wItemIndex == 0 || wItemIndex >= npList->wCount)
  377.    {
  378.       GlobalUnlock(hListHead);
  379.       return(AddListItem(hListHead, hItemData));
  380.    }
  381.  
  382.    hItem = GetListItemNode(hListHead, wItemIndex);
  383.    if (hItem == NULL)
  384.    {
  385.       GlobalUnlock(hListHead);
  386.       return(FALSE);
  387.    }
  388.  
  389.    npItem = (NPLISTITEM) GlobalLock(hItem);
  390.  
  391.    hNewItem = CreateListItemNode(hItemData, npItem->hPrevItem, hItem);
  392.    if (hNewItem == NULL)
  393.    {
  394.       GlobalUnlock(hItem);
  395.       GlobalUnlock(hListHead);
  396.       return(FALSE);
  397.    }
  398.  
  399.    if (npItem->hPrevItem != NULL)
  400.    {
  401.       npPrevItem = (NPLISTITEM) GlobalLock(npItem->hPrevItem);
  402.       npPrevItem->hNextItem = hNewItem;
  403.       GlobalUnlock(npItem->hPrevItem);
  404.    }
  405.  
  406.    if (hItem == npList->hFirstItem)
  407.       npList->hFirstItem = hNewItem;
  408.  
  409.    npItem->hPrevItem = hNewItem;
  410.  
  411.    ++npList->wCount;
  412.    GlobalUnlock(hNewItem);
  413.    GlobalUnlock(hItem);
  414.    GlobalUnlock(hListHead);
  415.    return(TRUE);
  416. }
  417.  
  418.  
  419. /*--------------------------------------------------------------------*/
  420. /* SortLinkedList                                                     */
  421. /*                                                                    */
  422. /*     This function ...                                              */
  423. /*                                                                    */
  424. /*  Arguments:                                                        */
  425. /*                                                                    */
  426. /*     hListHead   = Handle of the lists header node.                 */
  427. /*                                                                    */
  428. /*  Globals:       None                                               */
  429. /*                                                                    */
  430. /*  Return:        None                                               */
  431. /*                                                                    */
  432. /*--------------------------------------------------------------------*/
  433.  
  434. BOOL FAR PASCAL SortLinkedList(HANDLE hListHead, WORD wFlags, FARPROC lpCompFunc)
  435. {
  436.    return(TRUE);
  437. }
  438.  
  439.  
  440. /*--------------------------------------------------------------------*/
  441. /* EnumListItems                                                      */
  442. /*                                                                    */
  443. /*     This function enumerates all list items in list order calling  */
  444. /*     a user supplied enumeration callback function for each item    */
  445. /*     in the list.                                                   */
  446. /*                                                                    */
  447. /*  Arguments:                                                        */
  448. /*                                                                    */
  449. /*     hListHead   = Handle of the lists header node.                 */
  450. /*     lpEnumFunc  = Pointer to an enumeration callback function      */
  451. /*                   with the following prototype...                  */
  452. /*                                                                    */
  453. /* BOOL FAR PASCAL EnumFunc(WORD wIndex, HANDLE hItemData, LONG lParam) */
  454. /*                                                                    */
  455. /*                   The enumeration function receives 3 args; the    */
  456. /*                   index of the item, and the handle to the items   */
  457. /*                   data.  The enum function can return TRUE  to     */
  458. /*                   continue the enumeration or FALSE to end it.     */
  459. /*                                                                    */
  460. /*  Globals:       None                                               */
  461. /*                                                                    */
  462. /*  Return:        Returns TRUE if all list items were enumerated or  */
  463. /*                 FALSE is enumeration was aborted early becuase     */
  464. /*                 users callback function returned FALSE             */
  465. /*--------------------------------------------------------------------*/
  466. BOOL FAR PASCAL EnumListItems(HANDLE hListHead,
  467.                               FARPROC lpEnumFunc,
  468.                               ENUM_MODE mode,
  469.                               LONG lParam)
  470. {
  471.    NPLISTHEAD npList;
  472.    NPLISTITEM npItem;
  473.    HANDLE     hItem;
  474.    HANDLE     hCurItem;
  475.    HANDLE     hItemData;
  476.    WORD       wIndex = 0;
  477.  
  478.    if (lpEnumFunc == NULL)
  479.       return (FALSE);
  480.  
  481.    npList = (NPLISTHEAD) GlobalLock(hListHead);
  482.    if (npList == NULL)
  483.       return (FALSE);
  484.  
  485.    hItem = (mode == ENUM_FORWARD) ? npList->hFirstItem : npList->hLastItem;
  486.    GlobalUnlock(hListHead);
  487.  
  488.    while (hItem != NULL)
  489.    {
  490.        hCurItem = hItem;
  491.        npItem = (NPLISTITEM) GlobalLock(hItem);
  492.        hItem = (mode == ENUM_FORWARD) ? npItem->hNextItem : npItem->hPrevItem;
  493.        GlobalUnlock(hItem);
  494.        npItem = (NPLISTITEM) GlobalLock(hCurItem);
  495.        hItemData = npItem->hItemData;
  496.        GlobalUnlock(hCurItem);
  497.        if ((*lpEnumFunc)(++wIndex, hItemData, lParam) == FALSE)
  498.            return(FALSE);
  499.    }
  500.  
  501.    return(TRUE);
  502. }
  503.  
  504.  
  505. /*--------------------------------------------------------------------*/
  506. /* GetListCount                                                      */
  507. /*                                                                    */
  508. /*     This function ...                                              */
  509. /*                                                                    */
  510. /*  Arguments:                                                        */
  511. /*                                                                    */
  512. /*     hListHead   = Handle to list header node                       */
  513. /*                                                                    */
  514. /*  Globals:       None                                               */
  515. /*                                                                    */
  516. /*  Return:        Returns number of items in the list.               */
  517. /*                                                                    */
  518. /*--------------------------------------------------------------------*/
  519. WORD FAR PASCAL GetListCount(HANDLE hListHead)
  520. {
  521.    NPLISTHEAD npList;
  522.    BOOL       wNoListItems;
  523.  
  524.    npList = (NPLISTHEAD) GlobalLock(hListHead);
  525.    
  526.    if(npList != (NPLISTHEAD)NULL)
  527.    {
  528.            wNoListItems = npList->wCount;
  529.    }
  530.    GlobalUnlock(hListHead);
  531.    return(wNoListItems);
  532. }
  533.  
  534. /*--------------------------------------------------------------------*/
  535. /* DestroyLinkedList                                                  */
  536. /*                                                                    */
  537. /*     This function ...                                              */
  538. /*                                                                    */
  539. /*  Arguments:                                                        */
  540. /*                                                                    */
  541. /*     hListHead   = Handle to list head.                             */
  542. /*                                                                    */
  543. /*  Globals:       None                                               */
  544. /*                                                                    */
  545. /*  Return:        Returns handle to item data or NULL if failed      */
  546. /*                                                                    */
  547. /*--------------------------------------------------------------------*/
  548. void FAR PASCAL DestroyLinkedList(HANDLE hListHead)
  549. {
  550.    WORD wNoListItems;
  551.    WORD wIndex;
  552.  
  553.    wNoListItems = GetListCount(hListHead);
  554.  
  555.    // delete all remaining list item nodes
  556.  
  557.    for (wIndex = wNoListItems; wIndex > 0; --wIndex)
  558.        DeleteListItem(hListHead, wIndex);
  559.  
  560.    // delete list header node
  561.  
  562.    GlobalFree(hListHead);
  563. }
  564.